import { createContext, Fragment, useContext } from "react";
import { ReactEditor } from "slate-react";
import { Transforms } from "slate";

import { useKeystone } from "@keystone-6/core/admin-ui/context";
import { RelationshipSelect } from "@keystone-6/core/fields/types/relationship/views/RelationshipSelect";

import { ToolbarButton } from "./primitives";
import { useStaticEditor } from "./utils";
import { useToolbarState } from "./toolbar-state";

export const DocumentFieldRelationshipsContext = createContext({});

export function useDocumentFieldRelationships() {
  return useContext(DocumentFieldRelationshipsContext);
}

export const DocumentFieldRelationshipsProvider =
  DocumentFieldRelationshipsContext.Provider;

export function withRelationship(editor) {
  const { isVoid, isInline } = editor;
  editor.isVoid = (element) => {
    return element.type === "relationship" || isVoid(element);
  };
  editor.isInline = (element) => {
    return element.type === "relationship" || isInline(element);
  };
  return editor;
}

export function RelationshipButton({ onClose }) {
  const {
    editor,
    relationships: { isDisabled },
  } = useToolbarState();
  const relationships = useContext(DocumentFieldRelationshipsContext);
  return (
    <Fragment>
      {Object.entries(relationships).map(([key, relationship]) => {
        return (
          <ToolbarButton
            key={key}
            isDisabled={isDisabled}
            onMouseDown={(event) => {
              event.preventDefault();
              Transforms.insertNodes(editor, {
                type: "relationship",
                relationship: key,
                data: null,
                children: [{ text: "" }],
              });
              onClose();
            }}
          >
            {relationship.label}
          </ToolbarButton>
        );
      })}
    </Fragment>
  );
}

export function RelationshipElement({ attributes, children, element }) {
  const keystone = useKeystone();
  const editor = useStaticEditor();
  const relationships = useContext(DocumentFieldRelationshipsContext);
  const relationship = relationships[element.relationship];
  const list = keystone.adminMeta.lists[relationship.listKey];
  const searchFields = Object.keys(list.fields).filter(
    (key) => list.fields[key].search
  );

  return (
    <span {...attributes}>
      <span contentEditable={false}>
        {relationship ? (
          <RelationshipSelect
            controlShouldRenderValue
            isDisabled={false}
            list={list}
            labelField={list.labelField}
            searchFields={searchFields}
            portalMenu
            state={{
              kind: "one",
              value:
                element.data === null
                  ? null
                  : {
                      id: element.data.id,
                      label: element.data.label || element.data.id,
                    },
              onChange(value) {
                const at = ReactEditor.findPath(editor, element);
                if (value === null) {
                  Transforms.removeNodes(editor, { at });
                } else {
                  Transforms.setNodes(editor, { data: value }, { at });
                }
              },
            }}
          />
        ) : (
          "Invalid relationship"
        )}
      </span>
      <span>{children}</span>
    </span>
  );
}
